package com.zyf.service;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONObject;
import com.zyf.service.audio.HandleAudioService;
import com.zyf.utils.*;
import it.sauronsoftware.jave.AudioAttributes;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncodingAttributes;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FrameRecorder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.*;


/**
 * 短视频制作处理类
 */
public class HandleGJLongVideoByCPUBP {

    private static final int MAXLENGTH = 2620;//GSV单次处理最大文本内容长度

    private static final double RATE = 0.002;

    private static final String TTSURL = "http://192.168.1.2:9880";

    private static final String REFPATH = "./参考音频/海晓有声书.wav";

    private static final String REFTEXT = "一个初秋的上午，玉泰茶馆开始营业，掌柜王立发兴致勃勃地坐在柜台上。";

    /**
     * 批量一键生成图签视频
     */
    public void batchMakeVideos(String folderPath) throws Exception {
        //先批量生成配音文件
        List<File> srcTxtFiles = FileUtil.loopFiles(folderPath, backfile -> backfile.isFile() && backfile.getName().endsWith(".txt"));
        List<File> txtFiles = new ArrayList<>();
        for (File file : srcTxtFiles) {
            List<File> mp4FinalList = FileUtil.loopFiles(file.getParent(), mp4file -> mp4file.isFile() && mp4file.getName().endsWith(".mp4") && mp4file.getName().contains("zimufinal"));
            if (!ListUtil.isEmpty(mp4FinalList)) {
                continue;
            }
            txtFiles.add(file);
        }
        List<List<File>> pageList = splitList(txtFiles, 1);//30个一批进行处理
        List<String> errorFile = new ArrayList<>();
        for (List<File> pages : pageList) {
            List<File> handDataList = new ArrayList<>();
            for (File file : pages) {
                try {
                    handleTTSByLimit(TTSURL, REFPATH, REFTEXT, file.getAbsolutePath());
                    handDataList.add(file.getParentFile());
                } catch (Exception e) {
                    System.out.println(e.toString());
                    errorFile.add(e.toString());
                }
            }
            //遍历文件夹批量处理
            List<String> tips = new ArrayList<>();
            for (File file : handDataList) {
                try {
                    String fielfolderPath = file.getAbsolutePath();
                    List<File> backList = FileUtil.loopFiles(fielfolderPath, backfile -> backfile.isFile() && (backfile.getName().endsWith(".mp3") || backfile.getName().endsWith(".wav")) && backfile.getName().contains("back"));
                    List<File> srcList = FileUtil.loopFiles(fielfolderPath, srcfile -> srcfile.isFile() && (srcfile.getName().endsWith(".mp3") || srcfile.getName().endsWith(".wav")) && !srcfile.getName().contains("back"));
                    List<File> imgBackList = FileUtil.loopFiles(fielfolderPath, imgfile -> imgfile.isFile() && (imgfile.getName().endsWith(".jpg")) || imgfile.getName().contains(".png"));
                    if (ListUtil.isEmpty(imgBackList)) {
                        continue;
                    }
                    List<File> srctxtList = FileUtil.loopFiles(fielfolderPath, txtfile -> txtfile.isFile() && txtfile.getName().endsWith(".txt"));
                    makeVideoByTag(srcList.get(0).getAbsolutePath(), "", imgBackList.get(0).getAbsolutePath(), srctxtList.get(0).getAbsolutePath());
                    //删除多余的文件
                    List<File> mp4FinalList = FileUtil.loopFiles(fielfolderPath, mp4file -> mp4file.isFile() && mp4file.getName().endsWith(".mp4") && !mp4file.getName().contains("zimufinal"));
                    List<File> wavFinalList = FileUtil.loopFiles(fielfolderPath, wavfile -> wavfile.isFile() && wavfile.getName().endsWith(".wav") && (wavfile.getName().contains("hebing") || wavfile.getName().contains("back") || wavfile.getName().contains("merge")));
                    if (!ListUtil.isEmpty(mp4FinalList)) {
                        for (File mp4File : mp4FinalList) {
                            mp4File.delete();
                        }
                    }
                    if (!ListUtil.isEmpty(wavFinalList)) {
                        for (File wavFile : wavFinalList) {
                            wavFile.delete();
                        }
                    }
                } catch (Exception e) {
                    tips.add(e.toString());
                }
            }
        }
        System.out.println(errorFile.toString());
    }

    /**
     * 分割集合
     *
     * @param list
     * @param pageSize
     * @param <T>
     * @return
     */
    private <T> List<List<T>> splitList(List<T> list, int pageSize) {
        List<List<T>> pages = new ArrayList<>();
        int size = list.size();
        int pageCount = (size + pageSize - 1) / pageSize;
        for (int i = 0; i < pageCount; i++) {
            int fromIndex = i * pageSize;
            int toIndex = Math.min((i + 1) * pageSize, size);
            List<T> page = list.subList(fromIndex, toIndex);
            pages.add(page);
        }
        return pages;
    }

    /**
     * 调用GSV接口 9880
     *
     * @param txtFile
     * @return
     * @throws IOException
     */
    public void handleSingleTTS(String url, String refPath, String refText, String txtFile) throws Exception {
        File file = new File(txtFile);
        //读取源文件
        String srcContent = getSrcTxtByLine(txtFile);
        System.out.println("字符长度：" + srcContent.length());
        //设置请求参数
        StringBuffer param = new StringBuffer();
        param.append("text=" + URLEncoder.encode(srcContent, "utf-8"));
        param.append("&text_lang=zh&");
        param.append("ref_audio_path=" + URLEncoder.encode(refPath, "utf-8"));
        param.append("&prompt_lang=zh&");
        param.append("prompt_text=" + URLEncoder.encode(refText, "utf-8"));
        param.append("&text_split_method=cut5&batch_size=20&media_type=wav&speed_factor=1.0");

        HttpClientUtils.doGet(url, param.toString());
        //新文件夹路径
        String wavPath = "F:\\project\\GPT_SOVTTS\\GPT-SoVITS-v2\\音频输出\\audio.wav";
        String srtPath = "F:\\project\\GPT_SOVTTS\\GPT-SoVITS-v2\\音频输出\\tts-out.srt";
        //复制文件
        copyFile(wavPath, file.getParent());
        copyFile(srtPath, file.getParent());
    }

    /**
     * 调用GSV接口 9880
     *
     * @return
     * @throws IOException
     */
    public void handleSingleTTSByContent(String url, String refPath, String refText, String srcContent) throws Exception {
        //设置请求参数
        StringBuffer param = new StringBuffer();
        param.append("text=" + URLEncoder.encode(srcContent, "utf-8"));
        param.append("&text_lang=zh&");
        param.append("ref_audio_path=" + URLEncoder.encode(refPath, "utf-8"));
        param.append("&prompt_lang=zh&");
        param.append("prompt_text=" + URLEncoder.encode(refText, "utf-8"));
        param.append("&text_split_method=cut5&batch_size=20&media_type=wav&speed_factor=1.0");

        HttpClientUtils.doGet(url, param.toString());
        //新文件夹路径
        String wavPath = "F:\\project\\GPT_SOVTTS\\GPT-SoVITS-v2\\音频输出\\audio.wav";
        String srtPath = "F:\\project\\GPT_SOVTTS\\GPT-SoVITS-v2\\音频输出\\tts-out.srt";
        //复制文件
//        copyFile(wavPath, file.getParent());
//        copyFile(srtPath, file.getParent());
    }

    /**
     * 调用GSV接口 9880
     *
     * @param txtFile
     * @return
     * @throws IOException
     */
    public void handleSingleTTSByPost(String url, String refPath, String refText, String txtFile) throws Exception {
        File file = new File(txtFile);
        //读取源文件
        String srcContent = getSrcTxtByLine(txtFile);
        //设置请求参数
        JSONObject param = new JSONObject();
        param.put("text", srcContent);
        param.put("text_lang", "zh");
        param.put("ref_audio_path", URLEncoder.encode(refPath, "utf-8"));
        param.put("prompt_text", URLEncoder.encode(refText, "utf-8"));
        param.put("prompt_lang", "zh");


//        "aux_ref_audio_paths": [],    # list.(optional) auxiliary reference audio paths for multi-speaker tone fusion
//        "prompt_text": "",            # str.(optional) prompt text for the reference audio
//        "prompt_lang": "",            # str.(required) language of the prompt text for the reference audio
//        "top_k": 5,                   # int. top k sampling
//        "top_p": 1,                   # float. top p sampling
//        "temperature": 1,             # float. temperature for sampling
//        "text_split_method": "cut0",  # str. text split method, see text_segmentation_method.py for details.
//        "batch_size": 1,              # int. batch size for inference
//        "batch_threshold": 0.75,      # float. threshold for batch splitting.
//        "split_bucket: True,          # bool. whether to split the batch into multiple buckets.
//        "speed_factor":1.0,           # float. control the speed of the synthesized audio.
//        "streaming_mode": False,      # bool. whether to return a streaming response.
//        "seed": -1,                   # int. random seed for reproducibility.
//        "parallel_infer": True,       # bool. whether to use parallel inference.
//        "repetition_penalty": 1.35    # float. repetition penalty for T2S model.


        HttpClientUtils.doPost(url, param.toJSONString());
        //新文件夹路径
        String wavPath = "F:\\project\\GPT_SOVTTS\\GPT-SoVITS-v2\\音频输出\\audio.wav";
        String srtPath = "F:\\project\\GPT_SOVTTS\\GPT-SoVITS-v2\\音频输出\\tts-out.srt";
        //复制文件
        copyFile(wavPath, file.getParent());
        copyFile(srtPath, file.getParent());
    }

    public String getSrcTxtByLine(String filepath) throws FileNotFoundException {
        String[] punctuation = {"。", "，", "、", "；", "：", "？", "！", "•", ".", "—"};
        List<String> punctuations = Arrays.asList(punctuation);
        StringBuffer buffer = new StringBuffer();
        InputStream inputstream = new FileInputStream(new File(filepath));
        BufferedReader reader = null;
        String temp = "";
        try {
            reader = new BufferedReader(new InputStreamReader(inputstream));
            while (!StringUtil.isBlank(temp = reader.readLine())) {
                buffer.append(temp.trim());
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return buffer.toString();
    }

    /**
     * 一键合成文字书签视频
     *
     * @return
     * @throws Exception
     */
    public boolean makeVideoByTag(String audiopath, String backpath, String imgPath, String srctxtPath) throws Exception {
        try {
            //合成音频
            Map<String, String> resMap = mergeAudioAndBackBySrtAndTag(audiopath, backpath);
            //合成视频字幕
            String message = makeSingleVideo(imgPath, resMap.get("audio"), resMap.get("srt"), srctxtPath);//合成视频
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        return true;
    }

    /**
     * 生成封面图片
     *
     * @return
     */
    public String createCoverImgByContentByWidth(List<String> srclist, String imgpath, int imgWidth, int imgHeight, int fontsize) throws Exception {
        InputStream inputstream = null;
        BufferedImage bimage = null;
        int initTxtY = (imgHeight) / 2;
        String outpath = "";
        try {
            //图片加载到缓冲区
            inputstream = new FileInputStream(new File(imgpath));
            bimage = ImageIO.read(inputstream);
            File imgFile = new File(imgpath);
            outpath = imgFile.getParent() + File.separator + "cover.png";
            File file = new File(outpath);
            if (!file.exists()) {
                file.createNewFile();
            }
            Font font = new Font("楷体", Font.BOLD, fontsize);   //定义字体
            Color color = new Color(255, 255, 255, 255);
            for (int i = 0; i < srclist.size(); i++) {
                String temp = srclist.get(i);
                if (i < srclist.size() - 1) {
                    int res = ImageUtils.drawTextToImgByDefault(bimage, temp.trim(), outpath, font, initTxtY, color, imgWidth, fontsize);
                    initTxtY += fontsize + 10;//10个的间隔
                } else {
                    Font lastfont = new Font("楷体", Font.BOLD, fontsize - 40);   //定义字体
                    int res = ImageUtils.drawTextToImgByDefault(bimage, temp.trim(), outpath, lastfont, initTxtY, color, imgWidth, fontsize - 40);
                }

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            inputstream.close();
        }
        return outpath;
    }

    /**
     * 制作单个的长视频
     */
    public String makeSingleVideo(String backimgPath, String finalAudio, String finalSrt, String txtPath) throws Exception {
        //抓取内容视频的宽高
        FFmpegFrameGrabber grabberAudio = null;
        int coverWidth = 1300;
        int coverHeitht = 1800;
        long durationAudio = 0;
        double frameRate = 30;
        try {
            //抓取视频帧
            grabberAudio = new FFmpegFrameGrabber(finalAudio);
            grabberAudio.start();
            //获取时长,以短的文件为主进行截取
            durationAudio = grabberAudio.getFormatContext().duration() / 1000000;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (grabberAudio != null) {
                grabberAudio.stop();
                grabberAudio.release();
            }
        }
        //生成封面图片
        String retpng = resizeImage(backimgPath, coverWidth, coverHeitht);
        String coverimg = createCoverImgByContentByWidth(getThreelinesContent(txtPath), retpng, coverWidth, coverHeitht, 120);
        //1.将封面图片转成video
        System.out.println("-----开始将图片合成视频");
        long startTime=System.currentTimeMillis();
        String finalMa4Path = new File(backimgPath).getParent() + File.separator + "merge.mp4";
        createMp4ByFFmpegAndFrameRate(finalMa4Path, coverimg, coverWidth, coverHeitht, frameRate, Integer.valueOf(durationAudio + ""));//默认音频时长
        long imgToVideoTime=System.currentTimeMillis();
        System.out.println("-----将图片合成视频结束，用时："+(imgToVideoTime-startTime)/1000);
        //合成视频和音频
        System.out.println("开始合成视频和音频-----");
        String mp4path = mergeVediosAndAudio(finalMa4Path, finalAudio);
        long mergeAuVeTime=System.currentTimeMillis();
        System.out.println("-----合成视频和音频结束;用时："+(mergeAuVeTime-imgToVideoTime)/1000);
        //合并视频和字幕
        mergeVediosAndSrtByDoubleFile(mp4path, finalSrt);
        long mergeSrtVeTime=System.currentTimeMillis();
        System.out.println("-----合成视频和字幕结束;用时："+(mergeSrtVeTime-mergeAuVeTime)/1000);
        //合并视频和字幕
        return "操作成功";
    }

    public String resizeImage(String imgPath,
                              int width, int height) throws IOException {
        File imgFile = new File(imgPath);
        Image srcImg = ImageIO.read(imgFile);
        BufferedImage buffImg = null;
        buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //使用TYPE_INT_RGB修改的图片会变色
        buffImg.getGraphics().drawImage(
                srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0,
                0, null);
        String desPath = imgFile.getParent() + File.separator + "ret" + ".png";
        ImageIO.write(buffImg, "png", new File(desPath));
        return desPath;
    }

    /**
     * 合成单个视频和字幕
     *
     * @param videofile
     * @return
     * @throws Exception
     */
    public boolean mergeVediosAndSrtByDoubleFile(String videofile, String subtitleFile) throws Exception {
        subtitleFile = subtitleFile.replace("\\", "\\\\").replace(":", "\\:");
        String videoFinalfile = videofile.replace(".mp4", "_zimufinal.mp4");
        try {
            List<String> commands = new ArrayList<>();
            commands.add("ffmpeg");
            commands.add("-i");
            commands.add(videofile);
            commands.add("-filter_complex");
            commands.add("\"subtitles='" + subtitleFile + "':force_style='Alignment=2,MarginV=5,Fontsize=10'\"");
            commands.add("-c:a");
            commands.add("copy");
            commands.add(videoFinalfile);

            String res = FFmpegUtils.execFFmpegCommand(commands);
            System.out.println(res);
        } catch (Exception e) {
            throw new RuntimeException("ffmpeg执行异常" + e.getMessage());
        }
        return true;
    }

    /**
     * 读取源文件
     */
    private List<String> getThreelinesContent(String filepath) throws Exception {
        List<String> srcTxtlist = new ArrayList<>();
        InputStream inputstream = null;
        BufferedReader reader = null;
        String temp = "";
        try {
            Properties properties = getPropertiesByFile("mapping.txt");
            inputstream = new FileInputStream(new File(filepath));
            reader = new BufferedReader(new InputStreamReader(inputstream));
            int index = 0;
            while (StringUtil.isNotBlank(temp = reader.readLine())) {
                if (temp.length() > 0 && index < 3) {
                    if (temp.contains("《") && temp.contains("》")) {
                        srcTxtlist.add(temp.substring(0, temp.indexOf("。")));
                    } else if (temp.contains("第") && temp.contains("回")) {
                        String fielIndex = temp.substring(temp.indexOf("第") + 1, temp.indexOf("回")).trim();
                        srcTxtlist.add("第"+properties.getProperty(fielIndex)+"回");
                    } else {
                        srcTxtlist.add(temp);
                    }
                    index++;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputstream != null) {
                try {
                    inputstream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return srcTxtlist;
    }

    /**
     * 合并视频和音频,以长度短的为基准
     * <p>
     * ffmpeg -i input_video.mp4 -i input_audio.mp3 -c:v copy -c:a aac -strict experimental -b:a 192k output_video.mp4
     *
     * @throws Exception
     */
    public String mergeVediosAndAudio(String videoPath, String audioPath) throws Exception {
        String videoFinalfile = videoPath.replace(".mp4", "_final.mp4");
        File file = new File(videoFinalfile);
        if (file.exists()) {
            file.delete();
        }
        try {
            List<String> commands = new ArrayList<>();
            commands.add("ffmpeg");
            commands.add("-i");
            commands.add(videoPath);
            commands.add("-i");
            commands.add(audioPath);
            commands.add("-c:v");
            commands.add("copy");
            commands.add("-c:a");
            commands.add("aac");
            commands.add("-strict");
            commands.add("experimental");
            commands.add("-b:a");
            commands.add("192k");
            commands.add(videoFinalfile);

            String res = FFmpegUtils.execFFmpegCommand(commands);
            System.out.println(res);
        } catch (Exception e) {
            throw new RuntimeException("ffmpeg执行异常" + e.getMessage());
        }
        return videoFinalfile;
    }


    /**
     * 创建mp4指定帧率
     *
     * @param mp4SavePath
     * @param width
     * @param height
     * @throws FrameRecorder.Exception
     */
    public static void createMp4ByFFmpegAndFrameRate(String mp4SavePath, String imgFile, int width, int height, double frameRate, int duration) throws Exception {
        File mp4File = new File(mp4SavePath);
        if (mp4File.exists()) {
            mp4File.delete();
        }

        List<String> commands = new ArrayList<>();
        commands.add("ffmpeg");
        commands.add("-loop");
        commands.add("1");
        commands.add("-framerate");
        commands.add(frameRate + "");
        commands.add("-i");
        commands.add(imgFile);
        commands.add("-t");
        commands.add(duration + "");
        commands.add("-c:v");
        commands.add("libx264");
        commands.add("-b:v");
        commands.add("2000k");
        commands.add("-crf");
        commands.add("18");
        commands.add("-pix_fmt");
        commands.add("yuv420p");
        commands.add("-s");
        commands.add(width + "X" + height);
        commands.add(mp4SavePath);

        String res = FFmpegUtils.execFFmpegCommand(commands);
        System.out.println(res);
    }

    /**
     * 音频添加背景乐并生成字幕文件(音量默认0.1)
     */
    public Map<String, String> mergeAudioAndBackBySrtAndTag(String srcaudiopath, String backpath) throws Exception {
        Map<String, String> resMap = new HashMap<>();
        File audioFile = new File(srcaudiopath);
        if (!audioFile.exists()) {
            throw new RuntimeException("源音频不存在");
        }
//        File backFile = new File(backpath);
//        if (!backFile.exists()) {
//            throw new RuntimeException("背景音频不存在");
//        }
        //统一转为wav无损模式
        if (audioFile.getName().endsWith(".mp3")) {
            srcaudiopath = converAudio(srcaudiopath);
        }
        try {
            //源音频生成字幕文件
            List<File> srtList = FileUtil.loopFiles(audioFile.getParent(), file -> file.isFile() && file.getName().endsWith(".srt"));
            resMap.put("srt", srtList.get(0).getAbsolutePath());
            //合成音频根据ffmpeg
//            String finalaudio = mixSingleAudioByFFmpeg(srcaudiopath, backpath);
//            //调大音量5倍
//            String finaleVolumeAudio = controAudioVolume(finalaudio, 6f);
            resMap.put("audio", srcaudiopath);
            List<File> srctxtList = FileUtil.loopFiles(audioFile.getParent(), file -> file.isFile() && file.getName().endsWith(".txt"));
            if (srctxtList == null || srctxtList.size() <= 0) {
                throw new RuntimeException("字幕源文件不存在");
            }
            File srcaudiopathfile = new File(srcaudiopath.replace(".wav", ".mp3"));
            if (srcaudiopathfile.exists()) {
                srcaudiopathfile.delete();
            }
            File backpathfile = new File(backpath.replace(".wav", ".mp3"));
            if (backpathfile.exists()) {
                backpathfile.delete();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return resMap;
    }

    /**
     * 调整音量大小
     * ffmpeg -i input.mp3 -af "volume=0.1" output.mp3
     * <p>
     * ffmpeg -i input.mp3 -af "volume=10dB" output.mp3
     */
    public String controAudioVolume(String audiopath, float volume) throws Exception {
        File audioFile = new File(audiopath);
        String fileName = audioFile.getName();
        if (!audioFile.exists()) {
            throw new RuntimeException("文件不存在");
        }
        String outpath = audiopath.replace(".", "_final_hebing.");
        //生成str字幕文件
        List<String> commands = new ArrayList<>();
        commands.add("ffmpeg");
        commands.add("-i");
        commands.add(audiopath);
        commands.add("-af");
        commands.add("\"volume=" + volume + "\"");
        commands.add(outpath);

        String result = FFmpegUtils.execFFmpegCommand(commands);
        System.out.println(result);
        return outpath;
    }

    /**
     * 指定音频添加指定背景乐,统一用wav无损模式处理音频
     * ffmpeg -i main_audio.mp3 -stream_loop -1 -i background_music.mp3 -filter_complex "[0:a][1:a]amix=inputs=2:duration=first" -c:a libmp3lame -qscale:a 2 output.mp3
     * ffmpeg -i main_audio.mp3 -i background_music.mp3 -filter_complex "[1:a]volume=0.5[a];[0:a][a]amix=inputs=2:duration=first" -c:a libmp3lame -qscale:a 2 output.mp3
     *
     * @throws IOException
     */
    public String mixSingleAudioByFFmpeg(String srcpath, String backpath) throws Exception {
        File audioFile = new File(srcpath);
        if (!audioFile.exists()) {
            throw new RuntimeException("主音频文件不存在");
        }
        File backFile = new File(backpath);
        if (!backFile.exists()) {
            throw new RuntimeException("背景音频文件不存在");
        }
        //格式统一转换为wav
        if (audioFile.getName().endsWith(".mp3")) {
            srcpath = converAudio(srcpath);
        }
        //格式统一转换为wav
        if (backFile.getName().endsWith(".mp3")) {
            backpath = converAudio(backpath);
        }
        String outpath = srcpath.replace(".", "_merge.");
        File outFile = new File(outpath);
        if (outFile.exists()) {
            outFile.delete();
        }

        //合并音频
        List<String> commands = new ArrayList<>();
        commands.add("ffmpeg");
        commands.add("-i");
        commands.add(srcpath);
        commands.add("-stream_loop");
        commands.add("-1");
        commands.add("-i");
        commands.add(backpath);
        commands.add("-filter_complex");
        commands.add("\"[1:a]volume=0.25[a];[0:a][a]amix=inputs=2:duration=first\"");
        commands.add("-c:a");
//        commands.add("libmp3lame");
        commands.add("pcm_s16le");//wav格式
        commands.add("-qscale:a");
        commands.add("2");
        commands.add(outpath);

        String result = FFmpegUtils.execFFmpegCommand(commands);
        System.out.println(result);

        return outpath;
    }

    public boolean isChinese(String str) {
        boolean isChinese = true;
        for (char c : str.toCharArray()) {
            if (!Character.isIdeographic(c)) {
                isChinese = false;
                break;
            }
        }
        return isChinese;
    }

    /**
     * 音频转换
     */
    public String converAudio(String audioFilePath) {
        File inaudioFile = new File(audioFilePath);
        if (!inaudioFile.exists()) {
            throw new RuntimeException("音频文件不存在");
        }
        String filename = inaudioFile.getName();
        if (filename.contains("mp3")) {//默认转wav
            String outFilePath = audioFilePath.replace(".mp3", ".wav");
            File outFile = new File(outFilePath);
            try {
                AudioAttributes audioAttributes = new AudioAttributes();
                audioAttributes.setCodec("pcm_s16le");
                audioAttributes.setBitRate(new Integer(128000));
                audioAttributes.setChannels(new Integer(2));
                audioAttributes.setSamplingRate(new Integer(44100));

                EncodingAttributes encodingAttributes = new EncodingAttributes();
                encodingAttributes.setFormat("wav");
                encodingAttributes.setAudioAttributes(audioAttributes);

                Encoder encoder = new Encoder();
                encoder.encode(inaudioFile, outFile, encodingAttributes);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return outFilePath;
        }
        if (filename.contains("wav")) {//默认转mp3
            String mp3FilePath = audioFilePath.replace(".wav", ".mp3");
            File outFile = new File(mp3FilePath);
            try {
                AudioAttributes audioAttributes = new AudioAttributes();
                audioAttributes.setCodec("libmp3lame");
                audioAttributes.setBitRate(new Integer(128080));
                audioAttributes.setChannels(new Integer(2));
                audioAttributes.setSamplingRate(new Integer(44100));

                EncodingAttributes encodingAttributes = new EncodingAttributes();
                encodingAttributes.setFormat("mp3");
                encodingAttributes.setAudioAttributes(audioAttributes);

                Encoder encoder = new Encoder();
                encoder.encode(inaudioFile, outFile, encodingAttributes);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return mp3FilePath;
        }
        return "";
    }


    /**
     * 处理诗词文件,移动背景音乐,视频
     */
    public void handleTXT(String txtFile, String videoFolder) throws Exception {
        File back = new File(txtFile);
        List<File> sourceFile = FileUtil.loopFiles(back.getParent(), file -> file.isFile() && (file.getName().endsWith(".mp3") || file.getName().endsWith(".wav")));
        List<File> mp4list = FileUtil.loopFiles(videoFolder, MP4file -> MP4file.isFile() && (MP4file.getName().endsWith(".mp4")));
        if (sourceFile == null || sourceFile.size() <= 0) {
            throw new RuntimeException("背景音乐不存在");
        }
        //创建一级文件夹
        String firstLevelFolder = txtFile.substring(0, txtFile.indexOf("."));
        File firstLevelFolderFile = new File(firstLevelFolder);
        if (!firstLevelFolderFile.exists()) {
            firstLevelFolderFile.mkdir();
        }
        //读取文本文件
        List<String> txtList = new ArrayList<>();
        StringBuffer buffer = new StringBuffer();
        InputStream inputstream = new FileInputStream(new File(txtFile));
        BufferedReader reader = null;
        String temp = "";
        try {
            reader = new BufferedReader(new InputStreamReader(inputstream));
            while ((temp = reader.readLine()) != null) {
                if (!StringUtil.isBlank(temp.trim())) {
                    if (temp.trim().contains("*********")) {
                        txtList.add(buffer.toString());
                        buffer = new StringBuffer();
                    } else {
                        buffer.append(temp.trim());
                        buffer.append("\n");
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputstream != null) {
                try {
                    inputstream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //对文件批量处理
        String[] punctuation = {"。", "、", "；", "：", "？", "！", "•", ".", "，", "\n"};
        List<String> punctuations = Arrays.asList(punctuation);
        for (String str : txtList) {
            String folderName = "";
            String filename = str.substring(str.length() - 10, str.length());
            for (char name : filename.toCharArray()) {
                String nameStr = name + "";
                if (!punctuations.contains(nameStr)) {
                    if (folderName.length() > 3) {
                        break;
                    }
                    folderName = folderName + name;
                }
            }
            File newFolder = new File(firstLevelFolder + File.separator + folderName);
            if (!newFolder.exists()) {
                newFolder.mkdir();
            }
            //复制背景音乐
            copyFile(sourceFile.get(0).getAbsolutePath(), newFolder.getAbsolutePath());
            int randomNumber = (int) (Math.random() * (mp4list.size()));
            //复制背景视频
            File videoFile = mp4list.get(randomNumber);
            copyFile(videoFile.getAbsolutePath(), newFolder.getAbsolutePath());
            //写入文件
            FileWriter writer = null;
            try {
                String finalpath = newFolder.getAbsolutePath() + File.separator + folderName + ".txt";
                writer = new FileWriter(finalpath, false);
                writer.write(str);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (writer != null) {
                    writer.flush();
                    writer.close();
                }
            }
        }
    }

    public void copyFile(String sourceFile, String desfolder) throws IOException {
        // 源文件路径
        Path source = Paths.get(sourceFile);
        // 目标文件夹路径
        Path destinationDir = Paths.get(desfolder);
        // 目标文件路径
        Path destination = destinationDir.resolve(source.getFileName());
        // 确保目标文件夹存在
        Files.createDirectories(destinationDir);
        // 使用Files.copy()方法复制文件到目标文件夹
        Files.copy(source, destination);
    }

    private void copyFileByName(String sourceFile, String desfolder, String fileName) throws IOException {
        // 源文件路径
        Path source = Paths.get(sourceFile);
        // 目标文件夹路径
        Path destinationDir = Paths.get(desfolder);
        // 目标文件路径
        Path destination = destinationDir.resolve(fileName);
        // 确保目标文件夹存在
        Files.createDirectories(destinationDir);
        // 使用Files.copy()方法复制文件到目标文件夹
        Files.copy(source, destination);
    }


    /**
     * 一键整理古籍图片和文件
     */
    public  void batchArrangeFiles(String txtFolder, String imgFolder, String title) throws Exception {
        List<File> txtList = FileUtil.loopFiles(txtFolder, srctxtfile -> srctxtfile.isFile() && srctxtfile.getName().endsWith(".txt"));
        List<File> imgList = FileUtil.loopFiles(imgFolder, imgfile -> imgfile.isFile() && imgfile.getName().endsWith(".png"));
        List<String> tips = new ArrayList<>();
        //通过txt文档创建文件夹并将文件和图片复制到新文件夹中
        for (File txtFile : txtList) {
            //创建一级文件夹
            String firstLevelFolder = txtFile.getAbsolutePath().substring(0, txtFile.getAbsolutePath().indexOf("."));
            File firstLevelFolderFile = new File(firstLevelFolder);
            if (!firstLevelFolderFile.exists()) {
                firstLevelFolderFile.mkdir();
            }
            //读取文本文件
            StringBuffer buffer = new StringBuffer();
            InputStream inputstream = new FileInputStream(txtFile);
            BufferedReader reader = null;
            String temp = "";
            FileWriter writer = null;
            try {
                reader = new BufferedReader(new InputStreamReader(inputstream));
                int index = 0;
                while ((temp = reader.readLine()) != null) {
                    temp = temp.trim();
                    if (!StringUtil.isBlank(temp)) {
                        if (index == 0) {
                            if (temp.contains("《")) {
                                buffer.append(title);
                                buffer.append("\n");
                                String[] titleArr = temp.split("《");
                                buffer.append(titleArr[0]);
                                buffer.append("\n");
                                buffer.append("《" + titleArr[1] + "。");
                                buffer.append("\n");
                            } else {
                                buffer.append(title);
                                buffer.append("\n");
                                buffer.append(txtFile.getName().substring(0, txtFile.getName().indexOf(".")));
                                buffer.append("\n");
                                String[] titleArr = temp.split("《");
                                buffer.append("《");
                                buffer.append(temp);
                                buffer.append("》");
                                buffer.append("。");
                                buffer.append("\n");
                            }

                        } else {
                            buffer.append(temp);
                            buffer.append("\n");
                        }
                    }
                    index++;
                }
                //写入文件
                String finalpath = firstLevelFolderFile.getAbsolutePath() + File.separator + txtFile.getName();
                writer = new FileWriter(finalpath, false);
                writer.write(buffer.toString());
                //复制背景图片
                File backFile = null;
                String txtFileName = txtFile.getName();
                String fielIndex = txtFileName.substring(txtFileName.indexOf("第") + 1, txtFileName.indexOf("回"));
                for (File imgFile : imgList) {
                    String imgFileName = imgFile.getName();
                    String imgFileIndex = imgFileName.substring(0, imgFileName.indexOf("."));
                    if (imgFileIndex.equals(fielIndex)) {
                        backFile = imgFile;
                        break;
                    }
                }

                new HandleGJLongVideoByCPUBP().copyFile(backFile.getAbsolutePath(), firstLevelFolderFile.getAbsolutePath());
            } catch (Exception e) {
                tips.add(txtFile.getAbsolutePath() + e.toString());
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (inputstream != null) {
                    try {
                        inputstream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (writer != null) {
                    writer.flush();
                    writer.close();
                }
            }
            if (tips.size() > 0) {
                System.out.println(tips.toString());
            }

        }
    }

    /**
     * 获取某一配置主体
     *
     * @return
     */
    public Properties getPropertiesByFile(String filename) {
        Properties properties = new Properties();
        InputStream inputstream = null;
        InputStreamReader reader = null;
        try {
            inputstream = this.getClass().getClassLoader().getResourceAsStream(filename);
            reader = new InputStreamReader(inputstream, "UTF-8");
            properties.load(reader);
            return properties;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                inputstream.close();
                reader.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * 根据txt的长度限制合成语音
     */
    public void handleTTSByLimit(String ttsUrl, String refPath, String refTxt, String txtpath) throws Exception {
        //生成文件夹
        File txtfile = new File(txtpath);
        if (!txtfile.exists()) {
            throw new RuntimeException("文本不存在");
        }
        //解析文本
        String content = getSrcTxtByLine(txtpath);
        //判断文本的长度,如果文本长度小于GSV允许最大长度，则直接用单个tts;否则拆分合成
        int lengthTxt = content.length();
        if (lengthTxt < MAXLENGTH) {
            handleSingleTTS(TTSURL, REFPATH, REFTEXT, txtpath);
            return;
        }
        String filename = txtfile.getName().substring(0, txtfile.getName().indexOf("."));
        File foleder = new File(txtfile.getParent() + File.separator + filename);
        if (!foleder.exists()) {
            foleder.mkdir();
        }
        int total = content.length();
        int circle = total / MAXLENGTH + 1;
        String[] punctuation = {"。", "？", "！"};
        List<String> punctuations = Arrays.asList(punctuation);
        List<String> conlist = new ArrayList<>();
        for (int i = 0; i < circle; i++) {
            String res = "";
            //判断此句有几个停顿
            int flag = 0;
            if (content.length() > MAXLENGTH) {
                int endindex = MAXLENGTH + 100;
                if (content.length() <= MAXLENGTH + 100) {
                    endindex = content.length();
                }
                String match = content.substring(MAXLENGTH, endindex);
                for (char st : match.toCharArray()) {
                    String puncStr = st + "";
                    if (punctuations.contains(puncStr)) {
                        break;
                    } else {
                        flag++;
                    }
                }
                if (flag > 0) {
                    res = content.substring(0, MAXLENGTH + flag + 1);
                } else {
                    res = content.substring(0, MAXLENGTH + 1);
                }
                content = content.substring(res.length());
            } else {
                res = content;
                content = content.substring(res.length());
            }
            if (!StringUtil.isBlank(res)) {
                conlist.add(res);
            }
        }
        //新文件夹路径
        String wavPath = "F:\\project\\GPT_SOVTTS\\GPT-SoVITS-v2\\音频输出\\audio.wav";
        String srtPath = "F:\\project\\GPT_SOVTTS\\GPT-SoVITS-v2\\音频输出\\tts-out.srt";
        //遍历生成语音合成文件
        for (int i = 0; i < conlist.size(); i++) {
            handleSingleTTSByContent(ttsUrl, refPath, refTxt, conlist.get(i));
            //复制文件
            copyFileByName(wavPath, foleder.getAbsolutePath(), "audio" + i + ".wav");
            copyFileByName(srtPath, foleder.getAbsolutePath(), "tts-out" + i + ".srt");
        }
        //合并多个音频
        String finalAudio = mergeMulAudiosByFFmpeg(foleder.getAbsolutePath());
        //合并srt
        mergeMulSrts(foleder.getAbsolutePath());
        //复制到父级文件夹
        copyFile(finalAudio, txtfile.getParent());
        //删除音频合并记录表
        File audioTxt = new File(txtfile.getParent() + File.separator + "audio.txt");
        if (audioTxt != null) {
            audioTxt.delete();
        }
        //删除拆分后的文件
        List<File> audioList = FileUtil.loopFiles(foleder.getAbsolutePath(), audiofile -> audiofile.isFile());
        for (File file : audioList) {
            if (file != null) {
                file.delete();
            }
        }
        //删除文件夹
        foleder.delete();
    }

    /**
     * 根据顺序合并多个srt文件
     *
     * @param absolutePath
     */
    public void mergeMulSrts(String absolutePath) throws Exception {
        List<File> srtList = FileUtil.loopFiles(absolutePath, audiofile -> audiofile.isFile() && audiofile.getName().endsWith(".srt"));
        srtList.sort(new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        StringBuffer buffer = new StringBuffer();
        String lastTimeVersion = "";
        int lastIndex = 0;
        FileWriter writer = null;
        try {
            for (int i = 0; i < srtList.size() - 1; i++) {
                if (i == 0) {
                    String first = srtList.get(i).getAbsolutePath();
                    Map res = getSrtFileByLine(first, buffer);
                    lastIndex = (int) res.get("lastIndex");
                    lastTimeVersion = (String) res.get("lastTimeVersion");
                }
                String currentPath = srtList.get(i + 1).getAbsolutePath();
                //读取第一个文件并提取最后的时间
                Map<String, Object> curRes = getBalSrtFileByLine(currentPath, buffer, lastIndex, lastTimeVersion);
                lastIndex = (int) curRes.get("lastIndex");
                lastTimeVersion = (String) curRes.get("lastTimeVersion");
            }
            //写入文件
            String finalpath = new File(absolutePath).getParent() + File.separator + "final.srt";
            writer = new FileWriter(finalpath, false);
            writer.write(buffer.toString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (writer != null) {
                writer.flush();
                writer.close();
            }
        }
    }

    /**
     * 读取剩下的srt的文档
     *
     * @param filepath
     * @param buffer
     * @return
     * @throws FileNotFoundException
     */
    public Map<String, Object> getBalSrtFileByLine(String filepath, StringBuffer buffer, int lastIndex, String lastTimeVersion) throws FileNotFoundException {
        InputStream inputstream = null;
        BufferedReader reader = null;
        String temp = "";
        Map<String, Object> result = new HashMap<>();
        try {
            inputstream = new FileInputStream(new File(filepath));
            reader = new BufferedReader(new InputStreamReader(inputstream));
            List<String> content = new ArrayList<>();
            String starttime = lastTimeVersion;
            int index = lastIndex;
            while ((temp = reader.readLine()) != null) {
                //判断是最后一行的时间戳
                try {
                    int begin = Integer.valueOf(temp);
                    continue;
                } catch (Exception e) {
                   //不做处理
                }
                int interval = 0;//前后时间间隔
                if (temp.contains("-->")) {
                    String[] times = temp.split("-->");
                    String firstTime = times[0].trim().replace(",", "");//开始时间串
                    String secondTime = times[1].trim().replace(",", "");//结束时间串
                    //统计开始时间
                    String[] firstTimeList = firstTime.split(":");
                    int firstTotalIntervalTime = Integer.valueOf(firstTimeList[0]) * 60 * 60 * 1000 + Integer.valueOf(firstTimeList[1]) * 60 * 1000 + Integer.valueOf(firstTimeList[2]);//firstLast.intValue();
                    String[] secondTimeList = secondTime.split(":");
                    int secondTotalIntervalTime = Integer.valueOf(secondTimeList[0]) * 60 * 60 * 1000 + Integer.valueOf(secondTimeList[1]) * 60 * 1000 + Integer.valueOf(secondTimeList[2]);//secondLast.intValue();
                    interval = secondTotalIntervalTime - firstTotalIntervalTime;

                    String curStarttimeTime = starttime.replace(",", "");//开始时间串
                    //统计开始时间
                    String[] startTimeList = curStarttimeTime.split(":");
//                    Double startLast= (Double.valueOf(startTimeList[2]))*1000;
                    int startTotalIntervalTime = Integer.valueOf(startTimeList[0].trim()) * 60 * 60 * 1000 + Integer.valueOf(startTimeList[1].trim()) * 60 * 1000 + Integer.valueOf(startTimeList[2]);//startLast.intValue();

                    buffer.append(index + 1);
                    buffer.append("\n");
                    buffer.append(starttime);
                    buffer.append(" --> ");
                    int localtime = startTotalIntervalTime + interval;
                    int time2 = 0;
                    int time3 = 0;
                    int time1=0;
                    if(localtime >=60*60*1000){
                        time1 = localtime / (60*60*1000);
                        int balanceTime = localtime % (60*60*1000);
                        if (balanceTime >= 60000) {
                            time2 = localtime / 60000;
                            time3 = localtime % 60000;
                        } else {
                            time3 = localtime;
                        }
                    }else if (localtime >= 60000) {
                        time2 = localtime / 60000;
                        time3 = localtime % 60000;
                    } else {
                        time3 = localtime;
                    }
                    StringBuffer time3Buffer = new StringBuffer();
                    buffer.append("0"+time1+":");
                    time3Buffer.append("0"+time1+":");
                    if (time2 < 10) {
                        buffer.append("0" + time2);
                        time3Buffer.append("0" + time2);
                    } else {
                        buffer.append(time2);
                        time3Buffer.append(time2);
                    }
                    buffer.append(":");
                    time3Buffer.append(":");
                    String time3Str = time3 + "";
                    if (time3 < 10000 && time3 >= 1000) {
                        buffer.append("0" + time3Str.substring(0, 1) + "," + time3Str.substring(1));
                        time3Buffer.append("0" + time3Str.substring(0, 1) + "," + time3Str.substring(1));
                    } else if (time3 < 1000) {
                        buffer.append("00" + "," + time3Str);
                        time3Buffer.append("00" + "," + time3Str);
                    } else {
                        buffer.append(time3Str.substring(0, 2) + "," + time3Str.substring(2));
                        time3Buffer.append(time3Str.substring(0, 2) + "," + time3Str.substring(2));
                    }
                    buffer.append("\n");
                    starttime = time3Buffer.toString();
                    content.add(time3Buffer.toString());
                    result.put("lastIndex", index + 1);
                    result.put("lastTimeVersion", time3Buffer.toString());
                    index++;
                } else {
                    buffer.append(temp.trim());
                    buffer.append("\n");
                }

            }
//            for (int i = content.size() - 1; i >= 0; i--) {
//                if (content.get(i).contains("-->")) {
//                    int innerlastIndex = Integer.valueOf(content.get(i - 1).trim());
//                    String innerlastTimeVersion = (content.get(i).split("-->"))[1];
//                    result.put("lastIndex", innerlastIndex);
//                    result.put("lastTimeVersion", innerlastTimeVersion);
//                    break;
//                }
//            }
        } catch (Exception e) {
            System.out.println(e.toString());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputstream != null) {
                try {
                    inputstream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    //读取第一个srt的文档
    public Map<String, Object> getSrtFileByLine(String filepath, StringBuffer buffer) throws FileNotFoundException {
        InputStream inputstream = null;
        BufferedReader reader = null;
        String temp = "";
        Map<String, Object> result = new HashMap<>();
        try {
            inputstream = new FileInputStream(new File(filepath));
            reader = new BufferedReader(new InputStreamReader(inputstream));
            List<String> content = new ArrayList<>();
            while ((temp = reader.readLine()) != null) {
                buffer.append(temp.trim());
                buffer.append("\n");
                //判断是最后一行的时间戳
                content.add(temp.trim());
            }
            for (int i = content.size() - 1; i >= 0; i--) {
                if (content.get(i).contains("-->")) {
                    int lastIndex = Integer.valueOf(content.get(i - 1).trim());
                    String lastTimeVersion = (content.get(i).split("-->"))[1];
                    result.put("lastIndex", lastIndex);
                    result.put("lastTimeVersion", lastTimeVersion.trim());
                    break;
                }
            }
            System.out.println(content.toString());
        } catch (Exception e) {
            System.out.println(e.toString());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputstream != null) {
                try {
                    inputstream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * 合并多个音频  ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp3
     */
    public String mergeMulAudiosByFFmpeg(String audiopath) throws Exception {
        List<File> totalFiles = FileUtil.loopFiles(audiopath, file -> file.isFile() && (file.getName().endsWith(".wav") || file.getName().endsWith(".mp3")));
        List<File> audioFiles = new ArrayList<>();
        for (File file : totalFiles) {
            //转换格式为wav
            if (file.getName().endsWith(".mp3")) {
                String newpath = new HandleAudioService().converAudio(file.getAbsolutePath());
                audioFiles.add(new File(newpath));
            }
            if (file.getName().endsWith(".wav")) {
                audioFiles.add(file);
            }
        }
        audioFiles.sort(new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        StringBuffer buffer = new StringBuffer();
        for (File file : audioFiles) {
            buffer.append("file");
            buffer.append(" ");
            buffer.append("'");
            buffer.append(file.getAbsolutePath());
            buffer.append("'");
            buffer.append("\n");
        }
        //保存txt
        String txtpath = audiopath + File.separator + "audio.txt";
        FileWriter writer = null;
        try {
            writer = new FileWriter(txtpath, false);
            writer.write(buffer.toString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (writer != null) {
                writer.flush();
                writer.close();
            }
        }
        String finalPath = audiopath + File.separator + "final.wav";
        List<String> commands = new ArrayList<>();
        commands.add("ffmpeg");
        commands.add("-f");
        commands.add("concat");
        commands.add("-safe");
        commands.add("0");
        commands.add("-i");
        commands.add(txtpath);
        commands.add("-c");
        commands.add("copy");
        commands.add(finalPath);

        String result = FFmpegUtils.execFFmpegCommand(commands);
        System.out.println(result);

        return finalPath;
    }


}
